package com.easymin.weixin.common.api;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.easymin.weixin.common.DataGrid;
import com.easymin.weixin.controller.v4.ResultTransport;
import com.easymin.weixin.entity.area.ChargeStartTime;
import com.easymin.weixin.entity.freight.Order;
import com.easymin.weixin.entity.freight.OrderReview;
import com.easymin.weixin.entity.freight.RoadLine;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class FreightApi {

	private static final Logger logger = LoggerFactory.getLogger(FreightApi.class);

	@Value("${module.freight.url}")
	private String freightApiGateway;

	@Autowired
	private RestTemplate restTemplate;

	/**
	 * 查询货车类型.
	 */
	public static final String FINDTRUCKTYPE = "api/orders/findTruckType.json?lat={lat}&lng={lng}&appKey={appKey}";
	/**
	 * 保存常用路线.
	 */
	public static final String SAVE_ROADLINE = "api/roadLine/create.json?waypoints={waypoints}&passengerId={passengerId}"
			+ "&addressName={addressName}&appKey={appKey}";
	/**
	 * 删除常用路线.
	 */
	public static final String DELETE_ROADLINE = "api/roadLine/delete.json?id={id}&appKey={appKey}";
	/**
	 * 查询常用路线.
	 */
	public static final String FIND_ROADLINE = "api/roadLine/findByRoadLineId.json?passengerId={passengerId}&appKey={appKey}";
	/**
	 * 查询附近货运司机.
	 */
	public static final String FIND_DRIVERS = "api/orders/findDrivers.json?lng={lng}&lat={lat}&truckTypeId={truckTypeId}&appKey={appKey}";
	/**
	 * 查询单个订单.
	 */
	public static final String FIND_ONE_ORDER = "api/orders/findByOrderId.json?orderId={orderId}&appKey={appKey}";
	/**
	 * 到达某个途径点.
	 */
	public static final String REACH = "api/orders/reach.json?orderId={orderId}&waypointId={waypointId}&appKey={appKey}";
	/**
	 * 分页查询乘客订单.
	 */
	public static final String FIND_ORDERS = "api/orders/findOrders.json?passengerId={passengerId}&appKey={appKey}";
	/**
	 * 评价订单.
	 */
	public static final String REVIEW_ORDER = "api/orderReview/review.json?orderId={orderId}&content={content}"
			+ "&score={score}&appKey={appKey}";
	/**
	 * 催单.
	 */
	public static final String HASTEN_ORDER = "api/orders/hasten.json?orderId={orderId}&appKey={appKey}";
	/**
	 * 销单.
	 */
	public static final String CANCEL_ORDER = "api/orders/cancel.json?orderId={orderId}&cause={cause}&isDriver={isDriver}&appKey={appKey}";
	/**
	 * 接单.
	 */
	public static final String JIEDAN_ORDER = "api/orders/update.json?orderId={orderId}&action={action}&appKey={appKey}";
	/**
	 * 拒单.
	 */
	public static final String REFUSE_ORDER = "api/orders/update.json?orderId={orderId}&employId={employId}"
			+ "&cause={cause}&action={action}&appKey={appKey}";
	/**
	 * 抢单.
	 */
	public static final String GRAB_ORDER = "api/orders/grab.json?orderId={orderId}&employId={employId}&employName={employName}"
			+ "&employPhone={employPhone}&employNo={employNo}&employPhoto={employPhoto}"
			+ "&employScore={employScore}&employCompanyId={employCompanyId}&appKey={appKey}";
	/**
	 * 开始执行订单.
	 */
	public static final String RUN_ORDER = "api/orders/update.json?orderId={orderId}&action={action}&appKey={appKey}";
	/**
	 * 到达预约地开始等待.
	 */
	public static final String WAIT_ORDER = "api/orders/update.json?orderId={orderId}&action={action}&appKey={appKey}";
	/**
	 * 查询货车位置(实际是司机位置).
	 */
	public static final String FIND_DRIVERBY_ID = "api/orders/findDriverById.json?driverId={driverId}&appKey={appKey}";
	/**
	 * 创建货运订单.
	 */
	public static final String CREATE = "api/orders/create.json?passengerName={passengerName}&passengerPhone={passengerPhone}"
			+ "&truckTypeId={truckTypeId}&truckTypeName={truckTypeName}&channelName={channelName}"
			+ "&startTime={startTime}&waypoint={waypoint}&preStartPrice={preStartPrice}"
			+ "&preMileage={preMileage}&preRunTime={preRunTime}&preRunTimePrice={preRunTimePrice}"
			+ "&budgetPay={budgetPay}&appKey={appKey}";
	/**
	 * V4查询单个货运订单.
	 */
	public static final String FIND_ONE_ORDER_V4 = "api/orders/v4/findByOrderId.json?orderId={orderId}&appKey={appKey}";
	/**
	 * V4查询货运车辆类型.
	 */
	public static final String QUERY_TYPE_V4 = "api/orders/v4/queryType?companyId={companyId}&appKey={appKey}";
	/**
	 * V4货运抢单.
	 */
	public static final String UPDATE_GRAB_V4 = "api/orders/v4/grab";
	/**
	 * V4接单.
	 */
	public static final String UPDATE_JIEDAN_V4 = "api/orders/v4/jiedan";
	/**
	 * V4拒单.
	 */
	public static final String UPDATE_REFUSE_V4 = "api/orders/v4/refuse";
	/**
	 * V4接单.
	 */
	public static final String UPDATE_RUN_V4 = "api/orders/v4/run";
	/**
	 * V4到达预约地开始等待.
	 */
	public static final String UPDATE_WAIT_V4 = "api/orders/v4/wait";
	/**
	 * V4司机端销单.
	 */
	public static final String UPDATE_CANCEL_V4 = "api/orders/v4/cancel";
	/**
	 * V4到达.
	 */
	public static final String UPDATE_REACH_V4 = "api/orders/v4/reach";

	public static final String COUNT_NOTPAYAMOUNTS = "api/orders/countByPassengerId.json?passengerId={passengerId}&appKey={appKey}";

	public static final String COUNT_RUNNINGS = "api/orders/countRunning.json?passengerId={passengerId}&appKey={appKey}";

	/**
	 * 查询未完成订单数量数量
	 */
	public static final String COUNT_NOTFINISHEDAMOUNTS = "api/orders/queryRunOrder.json?passengerId={passengerId}&appKey={appKey}";

	/**
	 * 创建货运订单.
	 * 
	 * @param passengerId
	 *            客戶id
	 * @param passengerName
	 *            客戶名字
	 * @param passengerPhone
	 *            客戶电话
	 * @param companyId
	 *            公司id
	 * @param companyName
	 *            公司名称
	 * @param truckTypeId
	 *            类型id
	 * @param truckTypeName
	 *            类型名称
	 * @param channelName
	 *            来源名称
	 * @param startTime
	 *            开始时间
	 * @param waypoint
	 *            途径点
	 * @param memo
	 *            备注
	 * @param flitting
	 *            是否需要搬运
	 * @param receipt
	 *            是否需要回单
	 * @param receivedPay
	 *            是否需要回款
	 * @param payMount
	 *            回款金额
	 * @param preMileagePrice
	 *            预算里程费
	 * @param couponId
	 *            优惠券id
	 * @param tip
	 *            小费
	 * @param preStartPrice
	 *            预算的起步价
	 * @param preMileage
	 *            预算里程
	 * @param preRunTime
	 *            预算时间 分钟
	 * @param preRunTimePrice
	 *            预算时间费用
	 * @param budgetPay
	 *            预算总价
	 * @param payDetail
	 *            预算详情
	 */

	public Map<String, Object> create(Long passengerId, String passengerName, String passengerPhone, Long companyId,
			String companyName, Long truckTypeId, String truckTypeName, String channelName, Long startTime,
			String waypoint, String memo, Boolean flitting, Boolean receipt, Boolean receivedPay, Double payMount,
			Double preMileagePrice, Long couponId, Double tip, Double preStartPrice, Double preMileage,
			Integer preRunTime, Double preRunTimePrice, Double budgetPay, String payDetail, String appKey) {
		Map<String, Object> map = new HashMap<String, Object>();
		Map<String, String> kv = new HashMap<>();
		StringBuilder builder = new StringBuilder(buildApi(CREATE));
		if (passengerId != null) {
			kv.put("passengerId", String.valueOf(passengerId));
			builder.append("&passengerId={passengerId}");
		}
		kv.put("passengerName", passengerName);
		kv.put("passengerPhone", passengerPhone);
		if (companyId != null) {
			kv.put("companyId", String.valueOf(companyId));
			builder.append("&companyId={companyId}");
		}
		if (StringUtils.isNotBlank(companyName)) {
			kv.put("companyName", companyName);
			builder.append("&companyName={companyName}");
		}
		kv.put("truckTypeId", String.valueOf(truckTypeId));
		kv.put("truckTypeName", truckTypeName);
		kv.put("channelName", channelName);
		kv.put("startTime", String.valueOf(startTime));
		kv.put("waypoint", waypoint);
		kv.put("appKey", appKey);
		if (StringUtils.isNotBlank(memo)) {
			kv.put("memo", memo);
			builder.append("&memo={memo}");
		}
		if (flitting != null) {
			kv.put("flitting", String.valueOf(flitting));
			builder.append("&flitting={flitting}");
		}
		if (receipt != null) {
			kv.put("receipt", String.valueOf(receipt));
			builder.append("&receipt={receipt}");
		}
		if (receivedPay != null) {
			kv.put("receivedPay", String.valueOf(receivedPay));
			builder.append("&receivedPay={receivedPay}");
		}
		if (payMount != null) {
			kv.put("payMount", String.valueOf(payMount));
			builder.append("&payMount={payMount}");
		}
		if (preMileagePrice != null) {
			kv.put("preMileagePrice", String.valueOf(preMileagePrice));
			builder.append("&preMileagePrice={preMileagePrice}");
		}
		if (couponId != null) {
			kv.put("couponId", String.valueOf(couponId));
			builder.append("&couponId={couponId}");
		}
		if (tip != null) {
			kv.put("tip", String.valueOf(tip));
			builder.append("&tip={tip}");
		}
		if (preStartPrice != null) {
			kv.put("preStartPrice", String.valueOf(preStartPrice));
			builder.append("&preStartPrice={preStartPrice}");
		}
		if (preMileage != null) {
			kv.put("preMileage", String.valueOf(preMileage));
			builder.append("&preMileage={preMileage}");
		}
		if (preRunTime != null) {
			kv.put("preRunTime", String.valueOf(preRunTime));
			builder.append("&preRunTime={preRunTime}");
		}
		if (preRunTimePrice != null) {
			kv.put("preRunTimePrice", String.valueOf(preRunTimePrice));
			builder.append("&preRunTimePrice={preRunTimePrice}");
		}
		if (budgetPay != null) {
			kv.put("budgetPay", String.valueOf(budgetPay));
			builder.append("&budgetPay={budgetPay}");
		}
		if (StringUtils.isNotBlank(payDetail)) {
			kv.put("payDetail", payDetail);
			builder.append("&payDetail={payDetail}");
		}
		try {
			String result = restTemplate.postForObject(builder.toString(), null, String.class, kv);
			JSONObject jsonObject = JSON.parseObject(result);
			int code = jsonObject.getIntValue("code");
			map.put("code", code);
			map.put("msg", jsonObject.getString("message"));
			if (code == 0) {
				String data = jsonObject.getString("data");
				Order order = JSON.parseObject(data.toString(), Order.class);
				map.put("data", order);
			}
		} catch (Exception ex) {
			logger.error(ex.getMessage());
			map.put("code", 500);
			map.put("msg", "内部服务器错误");
		}

		return map;
	}

	/**
	 * 保存常用路线.
	 */

	public Map<String, Object> saveRoadLine(String waypoints, Long passengerId, String addressName, String appKey) {
		Map<String, String> kv = new HashMap<String, String>();
		kv.put("waypoints", waypoints);
		kv.put("passengerId", String.valueOf(passengerId));
		kv.put("addressName", addressName);
		kv.put("appKey", appKey);
		String result = restTemplate.postForObject(buildApi(SAVE_ROADLINE), null, String.class, kv);
		JSONObject jo = JSON.parseObject(result);
		Map<String, Object> map = new HashMap<String, Object>();
		int code = jo.getIntValue("code");
		map.put("code", code);
		String message = jo.getString("message");
		map.put("msg", message);
		if (code == 0) {
			JSONObject data = jo.getJSONObject("data");
			RoadLine roadLine = JSON.parseObject(data.toString(), RoadLine.class);
			map.put("data", roadLine);
		}
		return map;
	}

	/**
	 * 删除常用路线.
	 */

	public Map<String, Object> deleteRoadLine(Long id, String appKey) {
		Map<String, String> kv = new HashMap<String, String>();
		kv.put("id", String.valueOf(id));
		kv.put("appKey", appKey);
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			restTemplate.delete(buildApi(DELETE_ROADLINE), kv);
			map.put("code", 0);
			map.put("msg", "删除成功");
			map.put("data", null);
		} catch (Exception ex) {
			map.put("code", -1);
			map.put("msg", "删除常用路线失败");
		}
		return map;
	}

	/**
	 * 查询常用路线.
	 */

	public Map<String, Object> findRoadLine(Long passengerId, String appKey) {
		Map<String, Object> map = new HashMap<String, Object>();
		Map<String, String> kv = new HashMap<String, String>();
		kv.put("passengerId", String.valueOf(passengerId));
		kv.put("appKey", appKey);
		String string = restTemplate.getForObject(buildApi(FIND_ROADLINE), String.class, kv);
		JSONObject jsonObject = JSON.parseObject(string);
		int code = jsonObject.getIntValue("code");
		map.put("code", code);
		map.put("msg", jsonObject.getString("message"));
		if (code == 0) {
			JSONArray data = jsonObject.getJSONArray("data");
			List<RoadLine> list = JSON.parseArray(data.toString(), RoadLine.class);

			map.put("data", list);
		}
		return map;
	}

	/**
	 * 查询单个订单.
	 */

	public Order findOneOrder(Long orderId, String appKey) {
		Map<String, String> kv = new HashMap<String, String>();
		kv.put("orderId", String.valueOf(orderId));
		kv.put("appKey", appKey);
		String string = restTemplate.getForObject(buildApi(FIND_ONE_ORDER), String.class, kv);
		JSONObject jsonObject = JSON.parseObject(string);
		int code = jsonObject.getIntValue("code");
		Order order = null;
		if (code == 0) {
			JSONObject data = jsonObject.getJSONObject("data");
			order = JSON.parseObject(data.toString(), Order.class);
		}
		return order;
	}

	/**
	 * 到达单个途经点.
	 */

	public Map<String, Object> reach(Long orderId, Long waypointId, String appKey) {
		Map<String, String> kv = new HashMap<String, String>();
		kv.put("orderId", String.valueOf(orderId));
		kv.put("waypointId", String.valueOf(waypointId));
		kv.put("appKey", appKey);
		String string = restTemplate.postForObject(buildApi(REACH), null, String.class, kv);
		JSONObject jsonObject = JSON.parseObject(string);
		int code = jsonObject.getIntValue("code");
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("code", code);
		map.put("msg", jsonObject.getString("message"));
		map.put("data", null);
		return map;
	}

	/**
	 * 查询单个订单.
	 */

	public Map<String, Object> findByOrderId(Long orderId, String appKey) {

		Map<String, Object> map = new HashMap<String, Object>();

		Map<String, String> kv = new HashMap<String, String>();
		kv.put("orderId", String.valueOf(orderId));
		kv.put("appKey", appKey);
		String string = restTemplate.getForObject(buildApi(FIND_ONE_ORDER), String.class, kv);
		JSONObject jsonObject = JSON.parseObject(string);
		int code = jsonObject.getIntValue("code");
		map.put("code", code);
		map.put("msg", jsonObject.getString("message"));
		if (code == 0) {
			JSONObject data = jsonObject.getJSONObject("data");
			Order order = JSON.parseObject(data.toString(), Order.class);
			Map<String, Object> orderMap = new HashMap<String, Object>();

			orderMap.put("id", order.getId());
			orderMap.put("created", order.getCreated().getTime());
			orderMap.put("orderNo", order.getOrderNo());
			orderMap.put("passengerId", order.getPassengerId());
			orderMap.put("passengerName", order.getPassengerName());
			orderMap.put("passengerPhone",
					StringUtils.isNotBlank(order.getAnonymousNumber()) ? order.getAnonymousNumber()
							: order.getPassengerPhone());
			orderMap.put("employId", order.getEmployId());
			orderMap.put("employName", order.getEmployName());
			orderMap.put("employPhone", StringUtils.isNotBlank(order.getAnonymousNumber()) ? order.getAnonymousNumber()
					: order.getEmployPhone());
			orderMap.put("employPhoto", order.getEmployPhoto());
			orderMap.put("employNo", order.getEmployNo());
			orderMap.put("employScore", order.getEmployScore());
			orderMap.put("truckTypeName", order.getTruckTypeName());
			orderMap.put("truckNumber", order.getTruckNumber());
			orderMap.put("companyId", order.getCompanyId());
			orderMap.put("companyName", order.getCompanyName());
			orderMap.put("status", order.getStatus());
			orderMap.put("startAddress", order.getStartAddress());
			orderMap.put("endAddress", order.getDestination());
			orderMap.put("serverTime", order.getStartTime().getTime());
			orderMap.put("wayPoints", order.getWaypoints());
			orderMap.put("review", order.getReview());
			orderMap.put("truckName", order.getTruckName());
			if (order.getOrderReviews() != null) {
				orderMap.put("orderScore", order.getOrderReviews().getScore());
				orderMap.put("orderContent", order.getOrderReviews().getContent());
			}
			orderMap.put("realPay", formatDouble(order.getRealPay()));
			orderMap.put("budgetPay", formatDouble(order.getBudgetPay()));
			orderMap.put("preMileage", formatDouble(order.getPremileage()));
			orderMap.put("preMileagePrice", formatDouble(order.getPremileagePrice()));
			orderMap.put("preRunTimePrice", formatDouble(order.getPrerunTimePrice()));
			orderMap.put("preStartPrice", formatDouble(order.getPreStartPrice()));
			orderMap.put("preTravelTime", order.getPretravelTime());
			orderMap.put("payDetail", order.getPayDetail());
			orderMap.put("treatment", order.getTreatment());
			map.put("data", orderMap);
		}
		return map;
	}

	/**
	 * 查询乘客订单.
	 */

	public Map<String, Object> findOrders(Long passengerId, Integer page, Integer rows, String appKey) {
		DataGrid<Map<String, Object>> dataGrid = new DataGrid<Map<String, Object>>();

		Map<String, String> kv = new HashMap<String, String>();
		StringBuilder builder = new StringBuilder(buildApi(FIND_ORDERS));
		kv.put("passengerId", String.valueOf(passengerId));
		if (page != null) {
			kv.put("page", String.valueOf(page));
			builder.append("&page={page}");
		}
		if (rows != null) {
			kv.put("rows", String.valueOf(rows));
			builder.append("&rows={rows}");
		}
		kv.put("appKey", appKey);
		String string = restTemplate.getForObject(builder.toString(), String.class, kv);
		JSONObject jsonObject = JSON.parseObject(string);
		int code = jsonObject.getIntValue("code");

		Map<String, Object> map = new HashMap<String, Object>();

		map.put("code", code);
		map.put("msg", jsonObject.getString("message"));
		List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
		if (code == 0) {
			JSONObject json = jsonObject.getJSONObject("data");
			long total = json.getLong("total");

			dataGrid.setTotal(total);
			List<Order> list = new ArrayList<Order>();

			JSONArray jsonArray = json.getJSONArray("rows");
			list = JSON.parseArray(jsonArray.toString(), Order.class);
			for (Order order : list) {
				Map<String, Object> orderMap = new HashMap<String, Object>();
				orderMap.put("id", order.getId());
				orderMap.put("created", order.getCreated().getTime());
				orderMap.put("orderNo", order.getOrderNo());
				orderMap.put("passengerId", order.getPassengerId());
				orderMap.put("passengerName", order.getPassengerName());
				orderMap.put("passengerPhone",
						StringUtils.isNotBlank(order.getAnonymousNumber()) ? order.getAnonymousNumber()
								: order.getPassengerPhone());
				orderMap.put("employId", order.getEmployId());
				orderMap.put("employName", order.getEmployName());
				orderMap.put("employPhone",
						StringUtils.isNotBlank(order.getAnonymousNumber()) ? order.getAnonymousNumber()
								: order.getEmployPhone());
				orderMap.put("employPhoto", order.getEmployPhoto());
				orderMap.put("employNo", order.getEmployNo());
				orderMap.put("employScore", order.getEmployScore());
				orderMap.put("truckTypeName", order.getTruckTypeName());
				orderMap.put("truckNumber", order.getTruckNumber());
				orderMap.put("companyId", order.getCompanyId());
				orderMap.put("companyName", order.getCompanyName());
				orderMap.put("status", order.getStatus());
				orderMap.put("startAddress", order.getStartAddress());
				orderMap.put("endAddress", order.getDestination());
				orderMap.put("serverTime", order.getStartTime().getTime());
				orderMap.put("wayPoints", order.getWaypoints());
				orderMap.put("review", order.getReview());
				if (order.getOrderReviews() != null) {
					orderMap.put("orderScore", order.getOrderReviews().getScore());
					orderMap.put("orderContent", order.getOrderReviews().getContent());
				}

				orderMap.put("realPay", formatDouble(order.getRealPay()));
				orderMap.put("budgetPay", formatDouble(order.getBudgetPay()));
				orderMap.put("preMileage", formatDouble(order.getPremileage()));
				orderMap.put("preMileagePrice", formatDouble(order.getPremileagePrice()));
				orderMap.put("preRunTimePrice", formatDouble(order.getPrerunTimePrice()));
				orderMap.put("preStartPrice", formatDouble(order.getPreStartPrice()));
				orderMap.put("preTravelTime", order.getPretravelTime());
				orderMap.put("payDetail", order.getPayDetail());
				orderMap.put("treatment", order.getTreatment());
				listMap.add(orderMap);
			}
			dataGrid.setRows(listMap);
			map.put("data", dataGrid);
		}
		return map;
	}

	/**
	 * 评价货运订单.
	 */

	public Map<String, Object> review(Long orderId, String content, Double score, String appKey) {
		Map<String, String> kv = new HashMap<String, String>();

		kv.put("orderId", String.valueOf(orderId));
		kv.put("content", content);
		kv.put("score", String.valueOf(score));
		kv.put("appKey", appKey);
		String result = restTemplate.postForObject(buildApi(REVIEW_ORDER), null, String.class, kv);
		JSONObject object = JSON.parseObject(result);
		int code = object.getIntValue("code");
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("code", 0);
		map.put("msg", object.getString("message"));
		if (code == 0) {
			OrderReview orderReview = JSON.parseObject(object.getJSONObject("data").toString(), OrderReview.class);
			map.put("data", orderReview);
		}

		return map;
	}

	/**
	 * 催单.
	 */

	public String hasten(Long orderId, String appKey) {
		Map<String, String> kv = new HashMap<String, String>();
		kv.put("orderId", String.valueOf(orderId));
		kv.put("appKey", appKey);
		String result = restTemplate.getForObject(buildApi(HASTEN_ORDER), String.class, kv);
		JSONObject jo = JSON.parseObject(result);

		if (jo.getIntValue("code") == 0) {
			return "success";
		} else {
			return "fail";
		}
	}

	/**
	 * 销单.
	 * 
	 * @param orderId
	 *            订单Id
	 * @param cause
	 *            销单原因
	 */

	public Map<String, Object> cancel(Long orderId, String cause, Boolean isDriver, String appKey) {
		Map<String, String> kv = new HashMap<String, String>();
		kv.put("orderId", String.valueOf(orderId));
		kv.put("cause", cause);
		kv.put("isDriver", String.valueOf(isDriver));
		kv.put("appKey", appKey);
		String result = restTemplate.postForObject(buildApi(CANCEL_ORDER), null, String.class, kv);
		JSONObject jo = JSON.parseObject(result);
		int code = jo.getIntValue("code");
		String message = jo.getString("message");
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("code", code);
		map.put("msg", message);
		return map;
	}

	/**
	 * 接单.
	 */

	public Map<String, Object> jiedan(Long orderId, String appKey) {
		Map<String, Object> map = new HashMap<String, Object>();
		Map<String, String> kv = new HashMap<String, String>();
		kv.put("orderId", String.valueOf(orderId));
		kv.put("action", "jiedan");
		kv.put("appKey", appKey);
		try {
			restTemplate.put(buildApi(JIEDAN_ORDER), null, kv);
			map.put("msg", "接单成功");
			map.put("code", 0);
		} catch (Exception ex) {
			logger.error(ex.getMessage());
			map.put("code", 500);
			map.put("msg", "接单失败");
		}
		return map;
	}

	/**
	 * 拒单.
	 * 
	 * @param orderId
	 *            拒接订单id
	 * @param employId
	 *            拒单的服务人员id
	 * @param cause
	 *            拒单理由
	 */

	public Map<String, Object> refuse(Long orderId, Long employId, String cause, String appKey) {
		Map<String, Object> map = new HashMap<String, Object>();
		Map<String, String> kv = new HashMap<String, String>();
		kv.put("orderId", String.valueOf(orderId));
		kv.put("employId", String.valueOf(employId));
		kv.put("cause", cause);
		kv.put("action", "refuse");
		kv.put("appKey", appKey);
		try {
			restTemplate.put(buildApi(REFUSE_ORDER), null, kv);
			map.put("msg", "拒单成功");
			map.put("code", 0);
		} catch (Exception ex) {
			logger.error(ex.getMessage());
			map.put("msg", "拒单失败");
			map.put("code", 500);
		}
		return map;
	}

	/**
	 * 抢单.
	 */

	public Map<String, Object> grabOrder(Long orderId, Long employId, String employName, String employPhone,
			String employNo, Long employCompanyId, String employPhoto, Double employScore, String appKey) {
		Map<String, Object> map = new HashMap<String, Object>();
		Map<String, String> kv = new HashMap<String, String>();
		kv.put("orderId", String.valueOf(orderId));
		kv.put("employId", String.valueOf(employId));
		kv.put("employName", employName);
		kv.put("employPhone", employPhone);
		kv.put("employNo", employNo);
		kv.put("employCompanyId", String.valueOf(employCompanyId));
		kv.put("employPhoto", employPhoto);
		kv.put("employScore", String.valueOf(employScore));

		kv.put("appKey", appKey);

		try {
			String result = restTemplate.postForObject(buildApi(GRAB_ORDER), null, String.class, kv);
			JSONObject jsonObject = JSON.parseObject(result);
			int code = jsonObject.getIntValue("code");
			String message = jsonObject.getString("message");
			map.put("code", code);
			map.put("msg", message);
			if (code == 0) {
				JSONObject data = jsonObject.getJSONObject("data");
				Order order = JSON.parseObject(data.toString(), Order.class);
				map.put("data", order);
			}
		} catch (Exception ex) {
			logger.error(ex.getMessage());
			map.put("code", 500);
			map.put("msg", "");
		}
		return map;
	}

	/**
	 * 到达预约地.
	 */

	public Map<String, Object> waitOrder(Long orderId, String appKey) {
		Map<String, Object> map = new HashMap<String, Object>();
		Map<String, String> kv = new HashMap<String, String>();
		kv.put("orderId", String.valueOf(orderId));
		kv.put("action", "wait");
		kv.put("appKey", appKey);
		try {
			map.put("code", 0);
			map.put("msg", "到达预约地");
			restTemplate.put(buildApi(WAIT_ORDER), null, kv);
		} catch (Exception ex) {
			logger.error(ex.getMessage());
			map.put("code", 500);
			map.put("msg", "");
		}
		return map;
	}

	/**
	 * 开始执行订单.
	 */

	public Map<String, Object> runOrder(Long orderId, String appKey) {
		Map<String, Object> map = new HashMap<String, Object>();
		Map<String, String> kv = new HashMap<String, String>();
		kv.put("orderId", String.valueOf(orderId));
		kv.put("action", "run");
		kv.put("appKey", appKey);
		try {
			map.put("code", 0);
			map.put("msg", "执行订单成功");
			restTemplate.put(buildApi(RUN_ORDER), null, kv);
		} catch (Exception ex) {
			logger.error(ex.getMessage());
			map.put("code", 500);
			map.put("msg", "");
		}
		return map;
	}

	/**
	 * 查询当个订单.
	 */
	public ResultTransport findOrderV4(Long orderId, String address, String appKey) {
		Map<String, String> kv = new HashMap<String, String>();
		kv.put("orderId", String.valueOf(orderId));
		kv.put("appKey", appKey);

		String result = restTemplate.getForObject(buildApi(FIND_ONE_ORDER_V4), String.class, kv);

		ResultTransport orderTransport = JSON.parseObject(result, ResultTransport.class);

		if (orderTransport.getCode() == 0) {
			@SuppressWarnings("unchecked")
			Map<String, Object> map = (Map<String, Object>) orderTransport.getData();
			Object object2 = map.get("areaId");
			Long areaId = Long.valueOf(object2.toString());
			if (areaId != null) {
				StringBuilder builder2 = new StringBuilder();
				builder2.append(buildApiDaijia(address, "api/company/v4/findChargeStartTimes.json?areaId={areaId}"));
				String result2 = restTemplate.getForObject(builder2.toString(), String.class, areaId);
				ResultTransport areaTransport = JSON.parseObject(result2, ResultTransport.class);
				if (areaTransport.getCode() == 0) {
					List<ChargeStartTime> chargeStartTimes = JSON.parseArray(areaTransport.getData().toString(),
							ChargeStartTime.class);
					map.put("chargeStartTimes", chargeStartTimes);
				}
			}
			map.remove("areaId");
			orderTransport.setData(map);
		}
		return orderTransport;
	}

	/**
	 * 查询车型v4.
	 */

	public ResultTransport queryTypeV4(Long companyId, String appKey) {
		Map<String, String> kv = new HashMap<String, String>();
		kv.put("companyId", String.valueOf(companyId));
		kv.put("appKey", appKey);

		String result = restTemplate.getForObject(buildApi(QUERY_TYPE_V4), String.class, kv);
		ResultTransport parseObject = JSON.parseObject(result, ResultTransport.class);
		return parseObject;
	}

	/**
	 * 抢单V4.
	 */

	public ResultTransport grabV4(Long orderId, Long employId, String employName, String employPhone, Long companyId,
			String employAccount, String employPhoto, Double employScore, String appKey) {
		MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();
		kv.add("appKey", appKey);
		kv.add("orderId", String.valueOf(orderId));
		kv.add("employId", String.valueOf(employId));
		kv.add("employName", employName);
		kv.add("employPhone", employPhone);
		kv.add("employCompanyId", String.valueOf(companyId));
		kv.add("employNo", employAccount);
		kv.add("employScore", String.valueOf(employScore));
		if (StringUtils.isNotBlank(employPhoto)) {
			kv.add("employPhoto", employPhoto);
		}

		String result = postMultiValueMap(buildApi(UPDATE_GRAB_V4), kv);

		ResultTransport resultTransport = JSON.parseObject(result, ResultTransport.class);

		return resultTransport;
	}

	/**
	 * 接单V4.
	 */

	public ResultTransport jiedanV4(Long orderId, String appKey) {
		MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();
		kv.add("appKey", appKey);
		kv.add("orderId", String.valueOf(orderId));
		String result = postMultiValueMap(buildApi(UPDATE_JIEDAN_V4), kv);

		ResultTransport resultTransport = JSON.parseObject(result, ResultTransport.class);

		return resultTransport;
	}

	/**
	 * 拒单V4.
	 */

	public ResultTransport refuseV4(Long orderId, String cause, String appKey) {
		MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();
		kv.add("appKey", appKey);
		kv.add("orderId", String.valueOf(orderId));
		kv.add("cause", cause);
		String result = postMultiValueMap(buildApi(UPDATE_REFUSE_V4), kv);

		ResultTransport resultTransport = JSON.parseObject(result, ResultTransport.class);

		return resultTransport;
	}

	/**
	 * 出发V4.
	 */

	public ResultTransport runV4(Long orderId, String appKey) {
		MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();
		kv.add("appKey", appKey);
		kv.add("orderId", String.valueOf(orderId));
		String result = postMultiValueMap(buildApi(UPDATE_RUN_V4), kv);

		ResultTransport resultTransport = JSON.parseObject(result, ResultTransport.class);

		return resultTransport;
	}

	/**
	 * 到达预约地开始等待V4.
	 */

	public ResultTransport waitV4(Long orderId, String appKey) {
		MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();
		kv.add("appKey", appKey);
		kv.add("orderId", String.valueOf(orderId));
		String result = postMultiValueMap(buildApi(UPDATE_WAIT_V4), kv);

		ResultTransport resultTransport = JSON.parseObject(result, ResultTransport.class);

		return resultTransport;
	}

	/**
	 * 销单V4.
	 */

	public ResultTransport cancelV4(Long orderId, String cause, String appKey) {
		MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();
		kv.add("orderId", String.valueOf(orderId));
		kv.add("cause", cause);
		kv.add("appKey", appKey);

		String result = postMultiValueMap(buildApi(UPDATE_CANCEL_V4), kv);

		ResultTransport resultTransport = JSON.parseObject(result, ResultTransport.class);

		return resultTransport;
	}

	/**
	 * 到达单个途经点.
	 */

	public ResultTransport reachV4(Long orderId, Long waypointId, String appKey) {
		MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();
		kv.add("orderId", String.valueOf(orderId));
		kv.add("waypointId", String.valueOf(waypointId));
		kv.add("appKey", appKey);

		String result = postMultiValueMap(buildApi(UPDATE_REACH_V4), kv);

		ResultTransport resultTransport = JSON.parseObject(result, ResultTransport.class);

		return resultTransport;
	}

	private String buildApi(String api) {
		StringBuilder builder = new StringBuilder();
		builder.append(freightApiGateway);
		if (!freightApiGateway.endsWith("/")) {
			builder.append("/");
		}
		builder.append(api);
		return builder.toString();
	}

	private String buildApiDaijia(String server, String api) {

		StringBuilder builder = new StringBuilder();

		String daijiaServer = StringUtils.trimToEmpty(server).toLowerCase();
		if (!daijiaServer.startsWith("http://") && !daijiaServer.startsWith("https://")) {
			builder.append("http://");
		}
		builder.append(daijiaServer);
		if (!daijiaServer.endsWith("/")) {
			builder.append("/");
		}

		if (StringUtils.isNotBlank(api)) {
			builder.append(api);
		}

		return builder.toString();
	}

	public String postMultiValueMap(String url, MultiValueMap<String, String> kv) {
		return restTemplate.postForObject(url, kv, String.class);
	}

	/**
	 * 格式化double数字.
	 */

	private Double formatDouble(Double dou) {
		try {
			DecimalFormat df = new DecimalFormat("######0.00");
			String format = df.format(dou);
			Double valueOf = Double.valueOf(format);
			return valueOf;
		} catch (Exception ex) {
			return dou;
		}
	}

	/**
	 * 查询未支付订单数量.
	 */

	public Long countNotPayAmounts(Long passengerId, String appKey) {
		Long num = 0L;
		try {
			Map<String, String> kv = new HashMap<String, String>();

			kv.put("passengerId", String.valueOf(passengerId));
			kv.put("appKey", appKey);

			String result = restTemplate.getForObject(buildApi(COUNT_NOTPAYAMOUNTS), String.class, kv);

			JSONObject jo = JSON.parseObject(result);

			if (jo.getIntValue("code") == 0) {
				num = jo.getLongValue("data");
			}
		} catch (Exception ex) {
			logger.error(ex.getMessage());
		}
		return num;
	}

	/**
	 * 查询执行的订单数量.
	 */

	public Long countRunning(Long passengerId, String appKey) {
		Long num = 0L;
		try {
			Map<String, String> kv = new HashMap<String, String>();
			kv.put("passengerId", String.valueOf(passengerId));
			kv.put("appKey", appKey);
			String result = restTemplate.getForObject(buildApi(COUNT_RUNNINGS), String.class, kv);
			JSONObject jo = JSON.parseObject(result);
			if (jo.getIntValue("code") == 0) {
				num = jo.getLongValue("data");
			}
		} catch (Exception ex) {
			logger.error(ex.getMessage());
		}
		return num;
	}

	public Long countNotFinishedByPassenger(Long passengerId, String appKey) {

		Long num = 0L;
		try {
			Map<String, String> kv = new HashMap<String, String>();

			kv.put("passengerId", String.valueOf(passengerId));
			kv.put("appKey", appKey);

			String result = restTemplate.getForObject(buildApi(COUNT_NOTFINISHEDAMOUNTS), String.class, kv);

			JSONObject jo = JSON.parseObject(result);

			if (jo.getIntValue("code") == 0) {
				num = jo.getLongValue("data");
			}
		} catch (Exception ex) {
			logger.error(ex.getMessage());
		}
		return num;
	}

	// 获取货运优惠券
	private static final String GET_FREIGHT_COUPONS = "api/freight/listValidCouponsByPassenger?passengerId={passengerId}";

	/**
	 * 获取货运优惠券
	 * 
	 * @param server
	 *            代驾地址
	 * @param passengerId
	 *            用户ID
	 * @return JSONObject
	 */
	public JSONObject getCoupons(String server, Long passengerId) {
		String api = buildApiDaijia(server, GET_FREIGHT_COUPONS);
		String rs = restTemplate.getForObject(api, String.class, passengerId);
		if (null == rs || rs.isEmpty()) {
			return null;
		}
		JSONObject json = JSONObject.parseObject(rs);
		if (json.getIntValue("code") == 0) {
			return json;
		} else {
			return null;
		}
	}

	// 获取货运订单评价
	private static final String GET_FREIGHT_REVIRE = "api/orderReview/findReview?orderId={orderId}&appKey={appKey}";

	/**
	 * 获取货运订单评价
	 * 
	 * @param appKey
	 *            系统Key
	 * @param orderId
	 *            订单ID
	 * @return
	 */
	public JSONObject getFreightReview(String appKey, Long orderId) {
		String rs = restTemplate.getForObject(buildApi(GET_FREIGHT_REVIRE), String.class, orderId, appKey);
		if (null == rs || rs.isEmpty()) {
			return null;
		}
		JSONObject json = JSONObject.parseObject(rs);
		if (json.getIntValue("code") == 0) {
			return json;
		}
		return null;
	}

	// 货运微信支付
	private static final String FREIGHT_WX_PAY = "api/freight/wx/prepayId_jsapi?orderId={orderId}&openId={openId}";

	/**
	 * 获取微信支付信息
	 * 
	 * @param server
	 *            代驾地址
	 * @param orderId
	 *            订单ID
	 * @return
	 */
	public JSONObject getFreightWxPrepayId(String server, Long orderId, String openId) {
		String api = buildApiDaijia(server, FREIGHT_WX_PAY);
		String rs = restTemplate.postForObject(api, null, String.class, orderId, openId);
		return JSONObject.parseObject(rs);
	}

	// 获取用户未完成订单
	private static final String GET_NOT_SUCCESS_ORDERS = "api/orders/getNotSuccessOrder?passengerId={passengerId}&appKey={appKey}";

	/**
	 * 获取用户未完成订单
	 * 
	 * @param passengerId
	 * @param appKey
	 * @return
	 */
	public JSONObject getNotSuccessOrders(Long passengerId, String appKey) {
		String rs = restTemplate.getForObject(buildApi(GET_NOT_SUCCESS_ORDERS), String.class, passengerId, appKey);
		if (null == rs || rs.isEmpty()) {
			return null;
		}

		JSONObject json = JSONObject.parseObject(rs);
		if (json.getIntValue("code") == 0) {
			return json;
		}

		return null;
	}

}
